import { TelemetryPoint, TreeNode, TreeNodeStats, TreeBuilderConfig } from '../types/telemetry';

/**
 * 文件目录树构建器
 * 用于将遥测点数据按文件路径组织成树形结构
 */
export class FileTreeBuilder {
  private static readonly DEFAULT_CONFIG: TreeBuilderConfig = {
    includeEmptyDirs: false,
    maxDepth: 10,
    sortBy: 'name',
    groupByType: false,
  };

  /**
   * 构建目录树
   * @param points 遥测点数据
   * @param config 构建配置
   * @returns 树形结构数据
   */
  static buildTree(points: TelemetryPoint[], config: TreeBuilderConfig = {}): TreeNode {
    const finalConfig = { ...this.DEFAULT_CONFIG, ...config };

    console.log('🌳 [FileTreeBuilder] Starting tree construction with', points.length, 'telemetry points');

    // 创建根节点
    const root: TreeNode = {
      key: 'root',
      title: 'Chrome Components',
      path: '',
      level: 0,
      children: [],
      telemetryPoints: [],
      stats: this.calculateStats(points),
    };

    // 按路径分组遥测点
    const pathMap = new Map<string, TelemetryPoint[]>();

    points.forEach(point => {
      const normalizedPath = this.normalizePath(point.sourceFile);
      const pathParts = this.splitPath(normalizedPath);

      // 为每个路径层级创建分组
      for (let i = 0; i <= pathParts.length; i++) {
        const currentPath = pathParts.slice(0, i).join('/');
        const pathKey = currentPath || 'root';

        if (!pathMap.has(pathKey)) {
          pathMap.set(pathKey, []);
        }

        // 只在完整路径处添加遥测点
        if (i === pathParts.length) {
          pathMap.get(pathKey)!.push(point);
        }
      }
    });

    console.log('🌳 [FileTreeBuilder] Created', pathMap.size, 'unique path entries from', points.length, 'points');

    // 构建树形结构
    const allPaths = Array.from(pathMap.keys()).filter(path => path !== 'root');
    const sortedPaths = this.sortPaths(allPaths, finalConfig.sortBy);

    sortedPaths.forEach(path => {
      if (path) {
        this.addNodeToTree(root, path, pathMap.get(path) || [], finalConfig);
      }
    });

    // 排序子节点
    if (root.children) {
      root.children = this.sortChildren(root.children, finalConfig.sortBy);
    }

    // 统计最终结果
    const totalNodes = this.countAllNodes(root);
    const leafNodes = this.countLeafNodes(root);
    console.log('🌳 [FileTreeBuilder] Tree construction complete:', {
      totalNodes,
      leafNodes,
      maxDepth: this.getMaxDepth(root),
      rootChildren: root.children?.length || 0
    });

    return root;
  }

  /**
   * 标准化文件路径
   * @param path 原始路径
   * @returns 标准化后的路径
   */
  private static normalizePath(path: string): string {
    if (!path) return '';

    // 移除开头的斜杠，统一分隔符
    return path
      .replace(/^[/\\]+/, '')
      .replace(/\\/g, '/')
      .replace(/\/+/g, '/');
  }

  /**
   * 分割路径为各级目录
   * @param path 文件路径
   * @returns 路径分段数组
   */
  private static splitPath(path: string): string[] {
    if (!path) return [];

    // 保持完整路径，不移除文件扩展名，确保文件唯一性
    return path.split('/').filter(part => part.length > 0);
  }

  /**
   * 添加节点到树中
   * @param parent 父节点
   * @param path 节点路径
   * @param points 遥测点数据
   * @param config 构建配置
   */
  private static addNodeToTree(
    parent: TreeNode,
    path: string,
    points: TelemetryPoint[],
    config: TreeBuilderConfig
  ): void {
    const pathParts = path.split('/').filter(part => part.length > 0);
    let currentNode = parent;

    // 逐级创建或获取节点
    for (let i = 0; i < pathParts.length; i++) {
      const part = pathParts[i];
      const currentPath = pathParts.slice(0, i + 1).join('/');
      const isLeaf = i === pathParts.length - 1;

      // 查找是否已存在该节点
      let existingChild = currentNode.children?.find(child => child.path === currentPath);

      if (!existingChild) {
        // 创建新节点
        const newNode: TreeNode = {
          key: currentPath || 'root', // 使用完整路径确保唯一性
          title: this.formatNodeTitle(part, isLeaf),
          path: currentPath,
          isLeaf,
          level: (currentNode.level || 0) + 1,
          parentKey: currentNode.key,
          children: [],
          telemetryPoints: [],
        };

        if (!currentNode.children) {
          currentNode.children = [];
        }
        currentNode.children.push(newNode);
        existingChild = newNode;
      }

      currentNode = existingChild;
    }

    // 将遥测点数据添加到最终节点
    currentNode.telemetryPoints = points;
    currentNode.stats = this.calculateStats(points);

    // 如果不包含空目录，可以清理没有遥测点的目录
    if (!config.includeEmptyDirs && currentNode.children && currentNode.children.length === 0) {
      currentNode.children = undefined;
    }
  }

  /**
   * 格式化节点标题
   * @param name 节点名称
   * @param isLeaf 是否为叶子节点
   * @returns 格式化后的标题
   */
  private static formatNodeTitle(name: string, isLeaf: boolean): string {
    if (isLeaf) {
      // 对于文件，保持扩展名用于区分，但美化显示
      const baseName = name.replace(/\.[^.]*$/, ''); // 移除扩展名用于格式化
      const extension = name.match(/\.[^.]*$/)?.[0] || ''; // 保存扩展名

      let formattedName = baseName
        .replace(/[-_]/g, ' ')
        .replace(/\b\w/g, l => l.toUpperCase());

      // 对于重要文件类型，显示扩展名以区分不同文件
      if (['.xml', '.json', '.txt', '.md'].includes(extension)) {
        formattedName += extension; // 显示常见配置文件扩展名
      }

      return formattedName;
    }

    // 目录名保持原始格式，但做一些美化
    return name
      .replace(/[-_]/g, ' ')
      .replace(/\b\w/g, l => l.toUpperCase());
  }

  /**
   * 计算节点统计信息
   * @param points 遥测点数据
   * @returns 统计信息
   */
  static calculateStats(points: TelemetryPoint[]): TreeNodeStats {
    const stats: TreeNodeStats = {
      total: points.length,
      analyzed: 0,
      notAnalyzed: 0,
      needsCollection: 0,
      notNeeded: 0,
      analysisProgress: 0,
    };

    points.forEach(point => {
      switch (point.analysisStatus) {
        case 'ANALYZED':
          stats.analyzed++;
          break;
        case 'NOT_ANALYZED':
          stats.notAnalyzed++;
          break;
        case 'NEEDS_COLLECTION':
          stats.needsCollection++;
          break;
        case 'NOT_NEEDED':
          stats.notNeeded++;
          break;
      }
    });

    // 计算分析进度
    const completedCount = stats.analyzed + stats.notNeeded;
    stats.analysisProgress = stats.total > 0 ? Math.round((completedCount / stats.total) * 100) : 0;

    return stats;
  }

  /**
   * 递归统计子节点数据
   * @param node 树节点
   * @returns 包含子节点统计的完整统计
   */
  static calculateAggregatedStats(node: TreeNode): TreeNodeStats {
    let stats = node.stats ? { ...node.stats } : this.calculateStats(node.telemetryPoints || []);

    // 递归聚合子节点统计
    if (node.children) {
      node.children.forEach(child => {
        const childStats = this.calculateAggregatedStats(child);
        stats.total += childStats.total;
        stats.analyzed += childStats.analyzed;
        stats.notAnalyzed += childStats.notAnalyzed;
        stats.needsCollection += childStats.needsCollection;
        stats.notNeeded += childStats.notNeeded;
      });

      // 重新计算进度
      const completedCount = stats.analyzed + stats.notNeeded;
      stats.analysisProgress = stats.total > 0 ? Math.round((completedCount / stats.total) * 100) : 0;
    }

    return stats;
  }

  /**
   * 排序路径数组
   * @param paths 路径数组
   * @param sortBy 排序方式
   * @returns 排序后的路径
   */
  private static sortPaths(paths: string[], sortBy: 'name' | 'count' | 'status' = 'name'): string[] {
    return paths.sort((a, b) => {
      switch (sortBy) {
        case 'name':
          return a.localeCompare(b);
        case 'count':
          // 按路径深度排序（浅层优先）
          const aDepth = a.split('/').length;
          const bDepth = b.split('/').length;
          return aDepth - bDepth;
        case 'status':
          // 默认按名称排序
          return a.localeCompare(b);
        default:
          return a.localeCompare(b);
      }
    });
  }

  /**
   * 排序子节点
   * @param children 子节点数组
   * @param sortBy 排序方式
   * @returns 排序后的子节点
   */
  private static sortChildren(
    children: TreeNode[],
    sortBy: 'name' | 'count' | 'status' = 'name'
  ): TreeNode[] {
    return children.sort((a, b) => {
      switch (sortBy) {
        case 'name':
          return a.title.localeCompare(b.title);
        case 'count':
          const aCount = a.stats?.total || 0;
          const bCount = b.stats?.total || 0;
          return bCount - aCount; // 数量多的优先
        case 'status':
          const aProgress = a.stats?.analysisProgress || 0;
          const bProgress = b.stats?.analysisProgress || 0;
          return bProgress - aProgress; // 进度高的优先
        default:
          return a.title.localeCompare(b.title);
      }
    });
  }

  /**
   * 搜索树节点
   * @param tree 树形数据
   * @param searchTerm 搜索词
   * @returns 匹配的节点路径数组
   */
  static searchNodes(tree: TreeNode, searchTerm: string): string[] {
    const matches: string[] = [];
    const term = searchTerm.toLowerCase().trim();

    if (!term) return matches;

    const searchNode = (node: TreeNode): void => {
      // 检查当前节点是否匹配
      const nodeMatches = node.title.toLowerCase().includes(term) ||
        node.telemetryPoints?.some(point =>
          point.name.toLowerCase().includes(term) ||
          point.description?.toLowerCase().includes(term)
        );

      if (nodeMatches) {
        matches.push(node.key);
      }

      // 递归搜索子节点
      if (node.children) {
        node.children.forEach(searchNode);
      }
    };

    searchNode(tree);
    return matches;
  }

  /**
   * 根据路径查找节点
   * @param tree 树形数据
   * @param path 节点路径
   * @returns 找到的节点或null
   */
  static findNodeByPath(tree: TreeNode, path: string): TreeNode | null {
    const findNode = (node: TreeNode): TreeNode | null => {
      if (node.path === path) {
        return node;
      }

      if (node.children) {
        for (const child of node.children) {
          const found = findNode(child);
          if (found) return found;
        }
      }

      return null;
    };

    return findNode(tree);
  }

  /**
   * 获取节点的完整路径链
   * @param tree 树形数据
   * @param nodeKey 节点key
   * @returns 路径链数组
   */
  static getNodePath(tree: TreeNode, nodeKey: string): TreeNode[] {
    const path: TreeNode[] = [];

    const buildPath = (node: TreeNode): boolean => {
      path.push(node);

      if (node.key === nodeKey) {
        return true;
      }

      if (node.children) {
        for (const child of node.children) {
          if (buildPath(child)) {
            return true;
          }
        }
      }

      path.pop();
      return false;
    };

    buildPath(tree);
    return path;
  }

  /**
   * 统计所有节点数量
   * @param node 树节点
   * @returns 节点总数
   */
  private static countAllNodes(node: TreeNode): number {
    let count = 1; // 当前节点
    if (node.children) {
      node.children.forEach(child => {
        count += this.countAllNodes(child);
      });
    }
    return count;
  }

  /**
   * 统计叶子节点数量
   * @param node 树节点
   * @returns 叶子节点总数
   */
  private static countLeafNodes(node: TreeNode): number {
    if (!node.children || node.children.length === 0) {
      return 1; // 当前节点是叶子节点
    }
    let count = 0;
    node.children.forEach(child => {
      count += this.countLeafNodes(child);
    });
    return count;
  }

  /**
   * 获取树的最大深度
   * @param node 树节点
   * @returns 最大深度
   */
  private static getMaxDepth(node: TreeNode): number {
    if (!node.children || node.children.length === 0) {
      return node.level || 0;
    }
    let maxChildDepth = 0;
    node.children.forEach(child => {
      const childDepth = this.getMaxDepth(child);
      maxChildDepth = Math.max(maxChildDepth, childDepth);
    });
    return maxChildDepth;
  }
}